import java.io.FileInputStream;
import java.lang.reflect.Constructor;
import java.util.Properties;

public class AbstractFactoryPattern {
    public static void main(String[] args) {
        FoodFactroy factory = new BigFactory();
        Fruit bf = factory.createFruit();
        Vegetable bv = factory.createVegetable();
        bf.cultivate();
        bv.cultivate();
        FoodFactroy smFactroy = new SmallFactory();
        Fruit smf = smFactroy.createFruit();
        Vegetable smv = smFactroy.createVegetable();
        smf.cultivate();
        smv.cultivate();
        System.out.println("使用反射简化");
        SimpleFactory simpleFactory=new SimpleFactory();
        simpleFactory.createFruit().cultivate();
    }
}
/* 
 * 使用 反射+配置文件+简单工厂模式 改进抽象工厂模式
 */
class SimpleFactory {
    private String size = "Small";
   public  SimpleFactory (){
    
    Properties props = new Properties();
    try {
        FileInputStream fis = new FileInputStream("config.properties");
        props.load(fis);
        fis.close();
        this.size = props.getProperty("size");
    } catch (Exception e) {
    }
   }
    Fruit createFruit() {
        Fruit fruit = null;
        try {
            Class<?> clazz = Class.forName(size+"Fruit");
            Constructor<?> constructor = clazz.getDeclaredConstructor();

            fruit = (Fruit) constructor.newInstance();
        } catch (Exception e) {
        }
        return fruit;

    }

    Vegetable createVegetable(){
        Vegetable vegetable = null;
        try {
            Class<?> clazz = Class.forName(size+"Vegetable");
            Constructor<?> constructor = clazz.getDeclaredConstructor();

            vegetable = (Vegetable) constructor.newInstance();
        } catch (Exception e) {
        }
        return vegetable;
    }
}

/*
 * 食物工厂
 * 可以生产水果和蔬菜
 * 水果和蔬菜分别有大和小的
 * 
 * 如果想要添加中的 只需要添加MediumFruit、MediumVegetable、MediumFactory
 */
interface FoodFactroy {
    Fruit createFruit();

    Vegetable createVegetable();
}

class BigFactory implements FoodFactroy {

    @Override
    public Fruit createFruit() {

        return new BigFruit();
    }

    @Override
    public Vegetable createVegetable() {

        return new BigVegetable();
    }

}

class SmallFactory implements FoodFactroy {

    @Override
    public Fruit createFruit() {

        return new SmallFruit();
    }

    @Override
    public Vegetable createVegetable() {

        return new SmallVegetable();
    }

}

interface Fruit {
    void cultivate();
}

class SmallFruit implements Fruit {

    @Override
    public void cultivate() {
        System.out.println("cultivate SmallFruit");
    }

}

class BigFruit implements Fruit {

    @Override
    public void cultivate() {
        System.out.println("cultivate BigFruit");
    }

}

interface Vegetable {
    void cultivate();
}

class BigVegetable implements Vegetable {

    @Override
    public void cultivate() {
        System.out.println("cultivate BigVegetable");

    }

}

class SmallVegetable implements Vegetable {

    @Override
    public void cultivate() {
        System.out.println("cultivate SmallVegetable");

    }

}
